from datetime import *
import Core.Gadget as Gadget
import Core.WindFunctions as Wind
import Core.DataSeries as DataSeries
import Core.IO as IO
import re
import copy

# ---Call Wind Func, Save to Database---
# ---获取成分股及其权重---
def Request_Write_InstrumentList(database, datetime1, sectorName):

    #---
    values, datetime0 = Wind.WSet_InstrumentList(datetime1, sectorName)
    if values == None:
        return

    #print(str(data.Data[1].__len__()))
    name = sectorName + "_InstrumentList"
    # dataObjects = DataSeries.DataSeries(name)
    dataObject = {}
    # dataObject["DataSeries"] = name
    # dataObject["Symbol"] = sectorName
    # dataObject["Name"] = sectorName
    # dataObject["StdDateTime"] = Gadget.ToUTCDateTime(datetime0)
    # dataObject["DateTime"] = Gadget.ToDateTimeString(datetime0)
    # dataObject["Key"] = dataObject["DataSeries"] + "_" + dataObject["DateTime"]
    # dataObject["Values"] = values
    dataObject["InstrumentList"] = sectorName
    dataObject["DateTime"] = datetime1
    dataObject["Date"] = datetime1.date()

    #
    # dataObjects.add(dataObject)
    # database.saveDataSeries(dataObjects)

    documents = []
    for v in values:
        symbol = v["Symbol"]
        weight = v["Weight"]
        document = copy.deepcopy(dataObject)
        document["Symbol"] = symbol
        document["Weight"] = weight
        document["Key2"] = sectorName + "_" + Gadget.ToDateTimeString(datetime1) + "_" + symbol
        documents.append(document)

    database.Upsert_Many("Instruments", "InstrumentList", [], documents)


# ---更新债券列表---
def Request_Write_Bond_List(database, datetime1=None, forceToUpdate=False):

    if datetime1 == None:
        datetime1 = datetime.now()

    #
    instrumentsInDatabase = {}
    instruments = database.Find("Instruments", "Bond")
    for instrument in instruments:
        symbol = instrument["Symbol"]
        instrumentsInDatabase[symbol] = instrument

    #
    instrumentsInMap = {}
    instruments = database.Find("Instruments", "BondMap")
    for instrument in instruments:
        symbol = instrument["Symbol"]
        instrumentsInMap[symbol] = instrument


    # "证券公司债(银行间)"
    # "企业债(银行间)"
    # "全部交易所债券(未到期)"
    # "全部银行间及交易所债券(未到期)"
    # data, dt = Wind.WSet_Instruments(datetime1, sectorName="全部银行间及交易所债券(未到期)")
    data, dt = Wind.WSet_Instruments(datetime1, sectorName="证券公司债(银行间)")

    # IB, SH, SZ , BC 按照优先级重新排列Symbol顺序，保证 Major Symbol 是 IB based
    ibSymbols = []
    shSymbols = []
    szSymbols = []
    otherSymbols = []
    for d in data:
        symbol = d["Symbol"]
        exchange = symbol[-2:]
        if exchange == "IB":
            ibSymbols.append(symbol)
        elif exchange == "SH":
            shSymbols.append(symbol)
        elif exchange == "SZ":
            otherSymbols.append(symbol)

    symbols = ibSymbols + shSymbols + szSymbols + otherSymbols

    #
    count = 0
    step = 1000
    # for i in range(0, len(symbols), step):
    #    patialData = symbols[i:i + step]
    # for symbol in patialData:
    for symbol in symbols:
        count += 1
        print(symbol, count)

        # if symbol != "010007.IB":
        #    continue

        existed = instrumentsInMap.get(symbol)
        infoExisted = instrumentsInDatabase.get(symbol)
        if not existed:
            print("New Bond", symbol)
            data = Request_Bond_RelationCode(symbol)
            data = data[0]
            #
            dataObject = {}
            dataObject["Symbol"] = symbol
            dataObject["MajorSymbol"] = symbol
            #dataObject["Description"] = data["sec_name"]
            dataObject["Key"] = symbol
            # ---Add to Map---
            database.Upsert("Instruments", "BondMap", {"Key": symbol}, dataObject)
            instrumentsInMap[symbol] = dataObject
            #
            relationsCode = data["relationCode"]
            if relationsCode != None:
                relationsCodes = relationsCode.split(",")
                for code in relationsCodes:
                    #
                    if code in instrumentsInMap:
                        infoExisted = True

                    dataObject = {}
                    dataObject["Symbol"] = code
                    dataObject["MajorSymbol"] = symbol
                    #dataObject["Description"] = d["sec_name"]
                    dataObject["Key"] = code
                    # ---Save to Database---
                    database.Upsert("Instruments", "BondMap", {"Key": code}, dataObject)
                    # ---Add To Cache---
                    instrumentsInMap[symbol] = dataObject
        else:
            k = 1
            pass

        if not infoExisted:
            continue
            Download_BondInfo(database, symbol)


    # ---return date not None---
    print("Finish to Update Bond List")


def Download_BondInfo(database, symbol):
    print("Download BondInfo", symbol)
    data = Request_Bond_Info(symbol)
    data = data[0]
    # ---Generate Document---
    bondDocument = BondDocument(symbol, data)
    # ---Save to Database---
    database.Upsert("Instruments", "Bond", {"Key": symbol}, bondDocument)


def BondDocument(symbol, data):
    # ---Build Object---
    dataObject = {}
    dataObject["Symbol"] = symbol
    dataObject["Description"] = data["sec_name"]
    dataObject["Exchange"] = data["exch_eng"]
    dataObject["Term"] = data["term"]
    dataObject["CouponRate"] = data["couponrate"]
    dataObject["ActualBenchmark"] = data["actualbenchmark"]
    dataObject["InterestFrequency"] = data["interestfrequency"]
    dataObject["Type1"] = data["windl1type"]
    dataObject["Type2"] = data["windl2type"]
    dataObject["InstrumentType"] = "Bond"
    #
    dataObject["RelationCode"] = data["relationCode"]

    #
    dataObject["ListingDate"] = data["ipo_date"]
    dataObject["MaturityDate"] = data["maturitydate"]
    dataObject["CarryDate"] = data["carrydate"]
    dataObject["CarryEndDate"] = data["carryenddate"]

    #
    dataObject["DateTime1"] = Gadget.ToUTCDateTime(dataObject["CarryDate"])
    dataObject["DateTime2"] = Gadget.ToUTCDateTime(dataObject["CarryEndDate"])

    #
    dataObject["Key"] = dataObject["Symbol"]

    #
    return dataObject


def BuildBondMap(database):

    #
    datetime1 = datetime.now()
    data, dt = Wind.WSet_Instruments(datetime1, sectorName="全部银行间及交易所债券(未到期)")

    for d in data:
        symbol = d["Symbol"]
        dataObject = {}
        dataObject["Symbol"] = symbol
        dataObject["Description"] = d["sec_name"]
        dataObject["Key"] = symbol

        # ---Save to Database---
        database.upsert("Instruments", "BondMap", {"Key": d["Symbol"]}, dataObject)


def Request_Bond_RelationCode(symbol):
    #
    fields = ["relationCode"]
    params = {}
    params["exchangeType"] = "ALL"  # relationCode 的参数
    #
    data = Wind.WSS([symbol], fields, params)
    return data


def Request_Bond_Info(symbols):

    # ---Request Fields---
    fields = ["sec_name", "exch_eng", "ipo_date"]  #
    fields.append("par")  # 债券初始面值
    fields.append("issueamount")  # 发行总额(元)
    fields.append("carrydate")  # 起息日期
    fields.append("maturitydate")  # 到期日期
    fields.append("carryenddate")  # 计息截止日(比到期日早一天)
    fields.append("term")  # 债券期限(年)
    fields.append("interesttype")  # 利率类型
    fields.append("couponrate")  # 票面利率(发行时) X100
    # fields.append("paymenttype")  # 计息方式 单利复利
    fields.append("actualbenchmark")  # 计息基准 A/365
    fields.append("interestfrequency")  # 每年付息次数
    fields.append("windl1type")  # Wind债券一级分类
    fields.append("windl2type")  # Wind债券二级分类
    fields.append("relationCode")  # 跨市场代码

    #
    params = {}
    params["exchangeType"] = "ALL"  # relationCode 的参数
    #
    data = Wind.WSS(symbols, fields, params)
    return data






#---更新指数列表---
def Request_Write_Index_List(database, datetime1, symbols):

    #
    fields = ["sec_name","exch_eng","curr","country","crm_issuer","basedate","basevalue","numberofconstituents","launchdate"]
    data = Wind.WSS(symbols, fields)

    for iSymbol in range(len(symbols)):
        symbol = symbols[iSymbol]
        #
        dataObject = {}
        dataObject["Symbol"] = symbol
        dataObject["Description"] = data[iSymbol]["sec_name"]
        dataObject["Exchange"] = data[iSymbol]["exch_eng"]
        dataObject["Currency"] = data[iSymbol]["curr"]
        dataObject["Country"] = data[iSymbol]["country"]
        dataObject["Issuer"] = data[iSymbol]["crm_issuer"]
        dataObject["Base_Value"] = data[iSymbol]["basevalue"]
        dataObject["Number_of_Constituents"] = data[iSymbol]["numberofconstituents"]
        #
        baseDate = Gadget.FilterWindDateTimeDirty(data[iSymbol]["basedate"])
        datetime1 = Gadget.FilterWindDateTimeDirty(data[iSymbol]["launchdate"])
        launchDate = datetime1
        if datetime1 < datetime(1900,1,1):
            launchDate = baseDate
        #
        dataObject["Base_Date"] = baseDate
        dataObject["Launch_Date"] = launchDate
        dataObject["DateTime1"] = dataObject["Launch_Date"]
        dataObject["DateTime2"] = datetime(2100, 1, 1)
        dataObject["Key"] = symbol
        dataObject["Instrument_Type"] = "Index"
        #
        database.Upsert("financial_data", "instrument_index", {"Key": symbol}, dataObject)

    print("Finish to Update Index List")


if __name__ == '__main__':
    #
    from Core.Config import *
    config = Config()
    database = config.DataBase("MySQL")
    realtime = config.RealTime()

    Wind.w.start()
    Download_Option_List(database=database, realtime=realtime)
